package com.github.shiqiyue.myadmin.controller.system.createcode;

import com.baomidou.mybatisplus.plugins.Page;
import com.github.shiqiyue.myadmin.config.ApplicationConfig;
import com.github.shiqiyue.myadmin.config.security.anontation.Authority;
import com.github.shiqiyue.myadmin.config.security.anontation.AuthorityConfig;
import com.github.shiqiyue.myadmin.config.security.common.AuthorityCommon;
import com.github.shiqiyue.myadmin.controller.base.AdminBaseController;
import com.github.shiqiyue.myadmin.entity.system.Createcode;
import com.github.shiqiyue.myadmin.service.system.createcode.CreateCodeService;
import com.github.shiqiyue.myadmin.util.file.DelAllFile;
import com.github.shiqiyue.myadmin.util.file.FileZip;
import com.github.shiqiyue.myadmin.util.file.PathUtil;
import com.github.shiqiyue.myadmin.util.freemaker.Freemarker;
import com.github.shiqiyue.myadmin.util.string.CamelCaseUtils;
import com.github.shiqiyue.myadmin.util.web.FileDownload;
import com.github.shiqiyue.myadmin.vo.rep.base.RepBase;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.PrintWriter;
import java.util.*;

/***
 * 代码生成器-控制器
 * 
 * @author wwy
 *
 */
@Controller
@AuthorityConfig(prefix = "/admin/createCode/goPage")
@RequestMapping(value = "admin/createCode")
public class CreateCodeController extends AdminBaseController {
	
	@Autowired
	private CreateCodeService createcodeService;
	
	@Autowired
	private ApplicationConfig applicationConfig;
	
	/**
	 * 去列表页面
	 *
	 * @param
	 * @throws Exception
	 */
	@Authority(name = AuthorityCommon.LIST)
	@RequestMapping(value = "/goPage")
	public ModelAndView goPage() throws Exception {
		ModelAndView mv = this.getModelAndView();
		Integer totleCount = createcodeService.findCount();
		mv.addObject("totleCount", totleCount);
		mv.setViewName("system/createcode/createcode_list");
		// 按钮权限
		
		return mv;
	}
	
	/**
	 * 列表
	 *
	 * @param page
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Authority(name = AuthorityCommon.LIST)
	@RequestMapping(value = "/list")
	@ResponseBody
    public RepBase list(Page<Createcode> page, @RequestParam Map<String, Object> map) throws Exception {
        RepBase rep = new RepBase<>();
		// 列出CreateCode列表
		page = createcodeService.list(new Page<Createcode>(page.getCurrent(), page.getSize()), map);
		List<Createcode> varList = page.getRecords();
		Map<String, Object> resultInfo = new HashMap<>(2);
		resultInfo.put("data", varList);
		resultInfo.put("total", page.getTotal());
        return rep.setCommonSuccess().setData(resultInfo);
	}
	
	/**
	 * 去代码生成器页面(进入弹窗)
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/goProductCode")
	public ModelAndView goProductCode(String id) throws Exception {
		ModelAndView mv = this.getModelAndView();
		if (!"add".equals(id)) {
			Createcode create = createcodeService.findById(id);
			mv.addObject("pd", create);
			mv.addObject("msg", "edit");
		} else {
			mv.addObject("msg", "add");
		}
		mv.setViewName("system/createcode/productCode");
		return mv;
	}
	
	/**
	 * 生成代码
	 *
	 * @param response
	 * @throws Exception
	 */
	@Authority(name = AuthorityCommon.ADD)
	@RequestMapping(value = "/proCode")
	public void proCode(HttpServletResponse response, HttpServletRequest request, Createcode create) throws Exception {
		save(create);
		
		String describe = create.getDescribe();
		String packageName = create.getPackageName();
		String objectName = create.getObjectName();
		String tabletop = create.getTabletop();
		Integer zindex = create.getZindex();
		Short idType = create.getIdType();
		String author = create.getAuthor();
		List<String[]> fieldList = new ArrayList<>();
		String idTypeStr = "";
		for (int i = 0; i < zindex; i++) {
			String[] strs = new String[10];
			String[] strs2 = request.getParameter("field" + i).split(",fh,");
			System.arraycopy(strs2, 0, strs, 0, 6);
			strs[6] = CamelCaseUtils.toCamelCase(strs[0]);
			strs[7] = CamelCaseUtils.toCapitalizeCamelCase(strs[0]);
			fieldList.add(strs);
			
		}
		if (idType == 1 || idType == 4) {
			idTypeStr = "String";
		} else if (idType == 2 || idType == 3) {
			idTypeStr = "Long";
		}
		Map<String, Object> root = new HashMap<>(20);
		root.put("basePackage", applicationConfig.getBasePackage());
		root.put("idType", idType);
		root.put("idTypeStr", idTypeStr);
		root.put("fieldList", fieldList);
		root.put("TITLE", describe);
		root.put("packageName", packageName);
		root.put("objectName", objectName);
		root.put("objectNameLower", objectName.toLowerCase());
		root.put("objectNameUpper", objectName.toUpperCase());
		root.put("objectNameFirstLetterLower", firstLetterLowCase(objectName));
		root.put("objectNameCamel", CamelCaseUtils.toCamelCase(objectName));
		root.put("objectNameCamelCapital", CamelCaseUtils.toCapitalizeCamelCase(objectName));
		root.put("objectTable", strTransformation(objectName));
		root.put("tabletop", tabletop);
		root.put("nowDate", new Date());
		root.put("author", author);
		// 生成代码前,先清空之前生成的代码
		DelAllFile.delFolder(PathUtil.getClasspath() + "temp/ftl");
		// 存放路径
		String filePath = "temp/ftl/code/";
		// ftl路径
		String ftlPath = "createCode";
		/** 生成配置文件 */
		/* 生成controller */
		Freemarker.printFile("controllerTemplate.ftl", root,
				"controller/" + packageName + "/" + objectName.toLowerCase() + "/" + objectName + "Controller.java",
				filePath, ftlPath);
		
		/* 生成实体 */
		Freemarker.printFile("entity.ftl", root, "entity/" + packageName + "/" + objectName + ".java", filePath,
				ftlPath);
		
		/* 生成service */
		Freemarker.printFile("serviceTemplate.ftl", root,
				"service/" + packageName + "/" + objectName.toLowerCase() + "/" + objectName + "Service.java", filePath,
				ftlPath);
		Freemarker.printFile("mapperTemplate.ftl", root, "mapper/" + packageName + "/" + objectName + "Mapper.java",
				filePath, ftlPath);
		
		/* 生成mybatis xml */
		Freemarker.printFile("mapperMysqlTemplate.ftl", root,
				"mybatis_mysql/" + packageName + "/" + objectName + "Mapper.xml", filePath, ftlPath);
		
		/* 生成SQL脚本 */
		Freemarker.printFile("mysql_SQL_Template.ftl", root, "sql/" + tabletop + objectName.toLowerCase() + ".sql",
				filePath, ftlPath);
		
		/* 生成jsp页面 */
		Freemarker.printFile("jsp_list_Template.ftl", root,
				"jsp/" + packageName + "/" + objectName.toLowerCase() + "/" + objectName.toLowerCase() + "_list.jsp",
				filePath, ftlPath);
		Freemarker.printFile("jsp_edit_Template.ftl", root,
				"jsp/" + packageName + "/" + objectName.toLowerCase() + "/" + objectName.toLowerCase() + "_edit.jsp",
				filePath, ftlPath);
		
		String projectPath = getPorjectPath();
		String sourcePath = projectPath + "src//main//java//";
		String resourcePath = projectPath + "src//main//resources//";
		String webAppPath = projectPath + "src//main//webapp//";
		String basePackagePath = applicationConfig.getBasePackage().replaceAll("\\.", "/");
		
		/* 生成的全部代码压缩成zip文件 */
		if (FileZip.zip(PathUtil.getClasspath() + "temp/ftl/code", PathUtil.getClasspath() + "temp/ftl/code.zip")) {
			if (applicationConfig.getGenerateFile()) {
				// 拷贝文件到工程中
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "controller"),
						new File(sourcePath + basePackagePath + "/controller"));
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "entity"),
						new File(sourcePath + basePackagePath + "/entity"));
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "mapper"),
						new File(sourcePath + basePackagePath + "/mapper"));
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "service"),
						new File(sourcePath + basePackagePath + "/service"));
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "mybatis_mysql"),
						new File(resourcePath + "mybatis"));
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "jsp"),
						new File(webAppPath + "WEB-INF/jsp"));
				FileUtils.copyDirectory(new File(PathUtil.getClasspath() + filePath + "sql"),
						new File(resourcePath + "sql/create"));
			}
			
			/* 下载代码 */
			FileDownload.fileDownload(response, PathUtil.getClasspath() + "temp/ftl/code.zip", "code.zip");
		}
	}
	
	public String strTransformation(String str) {
		StringBuffer buffer = new StringBuffer();
		// 转为char数组
		char[] ch = str.toCharArray();
		buffer.append(String.valueOf(ch[0]).toLowerCase());
		// 得到大写字母
		for (int i = 1; i < ch.length; i++) {
			if (ch[i] >= 'A' && ch[i] <= 'Z') {
				buffer.append("_" + String.valueOf(ch[i]).toLowerCase());
			} else {
				buffer.append(ch[i]);
			}
		}
		return buffer.toString();
	}
	
	/**
	 * 保存到数据库
	 *
	 * @throws Exception
	 */
	public void save(Createcode pd) throws Exception {
		// 表名
		pd.setTableName(pd.getTabletop() + ",fh," + pd.getObjectName().toUpperCase());
		createcodeService.save(pd);
	}
	
	/**
	 * 删除
	 *
	 * @param out
	 */
	@Authority(name = AuthorityCommon.DELETE)
	@RequestMapping(value = "/delete")
	public void delete(PrintWriter out, String id) throws Exception {
		createcodeService.delete(id);
		out.write("success");
		out.close();
	}
	
	/**
	 * 批量删除
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Authority(name = AuthorityCommon.DELETE)
	@RequestMapping(value = "/deleteAll")
	@ResponseBody
    public RepBase deleteAll(String ids) throws Exception {
        RepBase rep = new RepBase<>();
		Map<String, Object> map = new HashMap<>(3);
		try {
			map.put("ids", ids);
			if (null != ids && !"".equals(ids)) {
				String[] idArray = ids.split(",");
				createcodeService.deleteAll(idArray);
				map.put("msg", "ok");
			} else {
				map.put("msg", "no");
			}
			map.put("pd", map);
		} catch (Exception e) {
			logger.error(e.toString(), e);
		} finally {
		}
        return rep.setCommonSuccess().setData(map);
	}
	
	private String firstLetterLowCase(String str) {
		StringBuffer sb = new StringBuffer(str);
		sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
		str = sb.toString();
		return str;
	}
	
	private String getPorjectPath() {
		String nowpath = "";
		nowpath = System.getProperty("user.dir") + "/";
		
		return nowpath;
	}
}
